package cn.schoolwow.quickdao.module.database.dml.instance.flow.delete.common;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.module.database.dml.common.domain.GetBatchParametersSupplier;
import cn.schoolwow.quickdao.module.database.dml.common.domain.ManipulationOption;
import cn.schoolwow.quickdao.module.database.parent.flow.executor.ExecuteBatchUpdateConnectionFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.util.domain.query.instance.QueryInstance;

import java.util.ArrayList;
import java.util.List;

public class DeleteByMultipleUniqueFieldNameFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        setStatement(flowContext);
        setParameters(flowContext);
        executeStatement(flowContext);
    }

    @Override
    public String name() {
        return "根据多个指定唯一字段列表删除实例";
    }

    private void setStatement(FlowContext flowContext) {
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        Entity entity = (Entity) flowContext.checkData("entity");
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);

        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append("delete from " + quickDAOConfig.databaseContext.databaseProvider.escape(entity.tableName) + " where ");
        for(String uniqueFieldName:manipulationOption.uniqueFieldNames){
            Property property = entity.getPropertyByFieldNameOrColumnName(uniqueFieldName);
            sqlBuilder.append(quickDAOConfig.databaseContext.databaseProvider.escape(property.column) + " = ? and ");
        }
        sqlBuilder.deleteCharAt(sqlBuilder.length() - 4);

        flowContext.putTemporaryData("sql", sqlBuilder.toString());
    }

    public void setParameters(FlowContext flowContext) {
        Entity entity = (Entity) flowContext.checkData("entity");
        Object instance = flowContext.getData("instance");
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);

        List<Object> parameters = new ArrayList();
        for(String uniqueFieldName:manipulationOption.uniqueFieldNames){
            Property property = entity.getPropertyByFieldNameOrColumnName(uniqueFieldName);
            Object value = QueryInstance.newQuery(instance)
                    .execute()
                    .getSingleFieldValue(property.name);
            if(null==value){
                throw new IllegalArgumentException("指定唯一字段的值不能为空!实体类:"+entity.clazz.getName()+",字段名:"+property.name);
            }
            parameters.add(value);
        }
        flowContext.putTemporaryData("parameters", parameters);
    }

    private void executeStatement(FlowContext flowContext) {
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);
        Object[] instances = (Object[]) flowContext.getData("instances", new Object[]{flowContext.checkData("instance")});

        flowContext.startFlow(new ExecuteBatchUpdateConnectionFlow())
                .putTemporaryData("perBatchCount", manipulationOption.perBatchCount)
                .putTemporaryData("name", "批处理根据指定唯一字段删除实例数组")
                .putTemporaryData("size", instances.length)
                .putTemporaryData("getBatchParametersSupplier",new GetBatchParametersSupplier() {
                    @Override
                    public List<Object> getBatchParameters(Integer index) throws Exception {
                        flowContext.putTemporaryData("instance", instances[index]);
                        setParameters(flowContext);
                        List<Object> parameters = (List<Object>) flowContext.checkData("parameters");
                        return parameters;
                    }
                })
                .execute();
    }
}
